﻿@using HardHatCore.HardHatC2Client.Pages;
@using System.Collections.Concurrent
@using HardHatCore.ApiModels.Shared.TaskResultTypes
@using HardHatCore.HardHatC2Client.Utilities

<MudTable T="FileSystemItem" Height="50vh" @ref=@_table Items="BodyContent.Values" HorizontalScrollbar="false" Virtualize="true" FixedHeader="true" Hover="true" Dense="true" Outlined="true" Striped="true" Filter="new Func<FileSystemItem,bool>(FilterFunc1)" SortLabel="Sort By">
    <ToolBarContent>
        @if (Path != null)
        {
            if(IsFileBrowser)
            {
                <MudTextField AdornmentColor="Color.Primary" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Folder" Class="mb-4 mt-4" @ref=FileBrowser.pathTextFiled TextChanged="@((s) =>FileBrowser.OnPathChanged(s))" @bind-Value="FileBrowser.targetPath" Label="@Path" Variant="Variant.Filled" />
            }
            else
            {
                <MudText Typo="Typo.h6">Directory Content of @Path</MudText>
            }
        }
        else
        {
            <MudText Typo="Typo.h6">Directory Content</MudText>
        }
        <MudSpacer/>
        <MudTextField Variant="Variant.Filled" @bind-Value="searchString1" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
        
    </ToolBarContent>
    <HeaderContent>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(0))">Name</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(1))">Length</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(2))">Owner</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(3))">Item Count</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(4))">CreationTimeUtc</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(5))">LastAccessTimeUtc</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(6))">LastWriteTimeUtc</MudTableSortLabel></MudTh>
        <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<List<FileSystemItem>, FileSystemItem>(x=>x.ElementAt(7))">ACLs</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd><MudIcon Size="Size.Small" Class="m-2" Color=@GetColor(context.Name) Icon=@getIcon(context.Name)></MudIcon> @context.Name</MudTd>
        <MudTd>@GetSize(context.Length)</MudTd>
        <MudTd>@context.Owner</MudTd>
        <MudTd>@context.ChildItemCount</MudTd>
        <MudTd>@context.CreationTimeUtc</MudTd>
        <MudTd>@context.LastAccessTimeUtc</MudTd>
        <MudTd>@context.LastWriteTimeUtc</MudTd>
        <MudTd>
            <MudTooltip Placement="Placement.Left" Arrow="true">
                <ChildContent>
                    <MudIconButton OnClick="@ToggleACLOpen" Size="Size.Small" Icon="@Icons.Material.Filled.People"/>
                </ChildContent>
                    <TooltipContent>
                    @if (context.ACLs != null)
                    {
                        <MudTable T="ACL" @ref=@_child_table Items="context.ACLs" HorizontalScrollbar="false" Virtualize="true" FixedHeader="true" Hover="true" Dense="true" Outlined="true" Striped="true" SortLabel="Sort By">
                            <HeaderContent>
                                <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<string[], string>(x => x.ElementAt(0))">Name</MudTableSortLabel></MudTh>
                                <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<string[], string>(x => x.ElementAt(1))">Type</MudTableSortLabel></MudTh>
                                <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<string[], string>(x => x.ElementAt(2))">Rights</MudTableSortLabel></MudTh>
                                <MudTh Style="@setStyle(Settings.IsCheckedBox)"><MudTableSortLabel SortBy="new Func<string[], string>(x => x.ElementAt(3))">Is Inherited</MudTableSortLabel></MudTh>
                            </HeaderContent>
                            <RowTemplate Context="childcontext">
                                <MudTd>@childcontext.IdentityRef</MudTd>
                                <MudTd>@childcontext.AccessControlType</MudTd>
                                <MudTd>@childcontext.FileSystemRights</MudTd>
                                <MudTd>@childcontext.IsInherited</MudTd>
                            </RowTemplate>
                            <PagerContent>
                                <MudTablePager HorizontalAlignment="HorizontalAlignment.Left" HidePageNumber="true" HidePagination="true"/>
                                <MudPagination SelectedChanged="PageChanged" Count="@((_child_table.GetFilteredItemsCount() + _child_table.RowsPerPage - 1) / _child_table.RowsPerPage)" Class="pb-3"/>
                            </PagerContent>
                        </MudTable>
                    }
                 </TooltipContent>
            </MudTooltip>
        </MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager HorizontalAlignment="HorizontalAlignment.Left" HidePageNumber="true" HidePagination="true"/>
        <MudPagination SelectedChanged="PageChanged" Count="@((_table.GetFilteredItemsCount() + _table.RowsPerPage - 1) / _table.RowsPerPage)" Class="pb-3"/>
    </PagerContent>
</MudTable>


@code {

    [Parameter]
    public List<FileSystemItem> Outputs {get; set;}
    [Parameter]
    public string Path {get; set;}
    [Parameter]
    public bool IsFileBrowser { get; set; } = false;
    public Dictionary<string, FileSystemItem> BodyContent = new Dictionary<string, FileSystemItem>();
    private MudTable<FileSystemItem>? _table;
    private MudTable<ACL>? _child_table;
    private string searchString1 = "";
    public bool _isOpen;


    public void ToggleACLOpen()
    {
        if (_isOpen)
            _isOpen = false;
        else
            _isOpen = true;
    }

    private string setStyle(bool IsDark)
    {
        if (IsDark)
        {
            return "background:white; color:black;";
        }
        return "background:#333333; color:white;";
    }

    //returns an icon depending on the name of the item 
    private string getIcon(string name)
    {
        //if name contains . followed by any character, it is a file if so return a file icon otherwise return a folder icon
        if (name.Contains("."))
        {

            // return icons for file extensions ending in .exe, .txt, .doc, .docx, .pdf, .png, .jpg, .jpeg, .gif, .bmp, .zip, .rar, .7z, .tar, .gz, .py, .ini, .pem, .ps1, .xlsx, .pptx, .cs
            if (name.EndsWith(".exe"))
            {
                return Icons.Material.Filled.Apps;
            }
            else if (name.EndsWith(".dll"))
            {
                return "fa fa-gears";
            }
            else if (name.EndsWith(".bin"))
            {
                return "fa fa-egg"; 
            }
            else if (name.EndsWith(".msi"))
            {
                return Icons.Custom.FileFormats.FileCode; 
            }
            else if (name.EndsWith(".txt"))
            {
                return Icons.Material.Filled.TextFields;
            }
            else if (name.EndsWith(".doc") || name.EndsWith(".docx"))
            {
                return Icons.Custom.FileFormats.FileWord;
            }
            else if (name.EndsWith(".pdf"))
            {
                return Icons.Custom.FileFormats.FilePdf;
            }
            else if (name.EndsWith(".png") || name.EndsWith(".jpg") || name.EndsWith(".jpeg") || name.EndsWith(".gif") || name.EndsWith(".bmp"))
            {
                return Icons.Material.Filled.Image;
            }
            else if (name.EndsWith(".zip") || name.EndsWith(".rar") || name.EndsWith(".7z") || name.EndsWith(".tar") || name.EndsWith(".gz"))
            {
                return Icons.Material.Filled.Archive;
            }
            else if (name.EndsWith(".ini"))
            {
                return Icons.Material.Filled.Settings;
            }
            else if (name.EndsWith(".pem"))
            {
                return Icons.Material.Filled.VpnKey;
            }
            else if (name.EndsWith(".ovpn"))
            {
                return Icons.Material.Filled.VpnKey;
            }

            else if (name.EndsWith(".xlsx") || name.EndsWith("xlsm"))
            {
                return Icons.Custom.FileFormats.FileExcel;
            }
            else if (name.EndsWith(".pptx"))
            {
                return "fa fa-file-powerpoint";
            }
            else if (name.EndsWith(".py"))
            {
                return "fa-brands fa-python";
            }
            else if (name.EndsWith(".ps1") || name.EndsWith(".psm1") || name.EndsWith(".psd1"))
            {
                return "fa fa-terminal";
            }
            //for all code endings return a File.Code icon 
            else if (name.EndsWith(".js") || name.EndsWith(".html") || name.EndsWith(".css") || name.EndsWith(".php") || name.EndsWith(".java") || name.EndsWith(".cpp") || name.EndsWith(".cs") || name.EndsWith(".c") || name.EndsWith(".h") || name.EndsWith(".bat") || name.EndsWith(".sh") || name.EndsWith(".cmd") || name.EndsWith(".vbs") || name.EndsWith(".vb") || name.EndsWith(".rb") || name.EndsWith(".go") || name.EndsWith(".swift") || name.EndsWith(".pl"))
            {
                return Icons.Custom.FileFormats.FileCode;
            }
            //for video files return videoLibrary icon
            else if (name.EndsWith(".mp4") || name.EndsWith(".mkv") || name.EndsWith(".avi") || name.EndsWith(".mov") || name.EndsWith(".wmv") || name.EndsWith(".flv") || name.EndsWith(".mpg") || name.EndsWith(".mpeg") || name.EndsWith(".m4v") || name.EndsWith(".webm"))
            {
                return Icons.Material.Outlined.VideoLibrary;
            }
            else
            {
                return Icons.Material.Filled.InsertDriveFile;
            }
        }
        return @Icons.Material.Filled.Folder;

    }

    //function to return the icon color based on the type or extesnion
    private Color GetColor(string name)
    {
        if (name.Contains("."))
        {
            if (name.EndsWith(".exe"))
            {
                return Color.Primary; 
            }
            else if (name.EndsWith(".dll"))
            {
                return Color.Default; 
            }
            else if (name.EndsWith(".bin"))
            {
                return Color.Secondary; 
            }
            else if (name.EndsWith(".msi"))
            {
                return Color.Error; 
            }
            else if (name.EndsWith(".txt"))
            {
                return Color.Default; 
            }
            else if (name.EndsWith(".doc") || name.EndsWith(".docx"))
            {
                return Color.Info;
            }
            else if (name.EndsWith(".pdf"))
            {
                return Color.Error;
            }
            else if (name.EndsWith(".png") || name.EndsWith(".jpg") || name.EndsWith(".jpeg") || name.EndsWith(".gif") || name.EndsWith(".bmp"))
            {
                return Color.Warning;
            }
            else if (name.EndsWith(".zip") || name.EndsWith(".rar") || name.EndsWith(".7z") || name.EndsWith(".tar") || name.EndsWith(".gz"))
            {
                return Color.Tertiary;
            }
            else if (name.EndsWith(".py"))
            {
                return Color.Success;
            }
            else if (name.EndsWith(".ini"))
            {
                return Color.Default;
            }
            else if (name.EndsWith(".pem"))
            {
                return Color.Dark;
            }
            else if (name.EndsWith(".ps1"))
            {
                return Color.Info;
            }
            else if (name.EndsWith(".xlsx") || name.EndsWith(".xlsm") )
            {
                return Color.Success;
            }
            else if (name.EndsWith(".pptx"))
            {
                return Color.Warning;
            }
            else if (name.EndsWith(".js") || name.EndsWith(".html") || name.EndsWith(".css") || name.EndsWith(".php") || name.EndsWith(".java") || name.EndsWith(".cpp") || name.EndsWith(".cs") || name.EndsWith(".c") || name.EndsWith(".h") || name.EndsWith(".bat") || name.EndsWith(".sh") || name.EndsWith(".cmd") || name.EndsWith(".vbs") || name.EndsWith(".vb") || name.EndsWith(".rb") || name.EndsWith(".go") || name.EndsWith(".swift") || name.EndsWith(".pl"))
            {
                return Color.Tertiary;
            }
            else if (name.EndsWith(".mp4") || name.EndsWith(".mkv") || name.EndsWith(".avi") || name.EndsWith(".mov") || name.EndsWith(".wmv") || name.EndsWith(".flv") || name.EndsWith(".mpg") || name.EndsWith(".mpeg") || name.EndsWith(".m4v") || name.EndsWith(".webm"))
            {
                return Color.Error;
            }
            else
            {
                return Color.Default;
            }
        }
        return Color.Default;
    }


    //function that can handle an event callback returning a bool for IsVisibleChanged
    //private void IsVisibleChangedCallback(bool isVisible)
    //{
    //    IsAclVisible = isVisible;
    //}

    public void FillContents()
    {
        foreach (FileSystemItem output in Outputs)
        {
            if (!BodyContent.ContainsKey(output.Name))
            {
                BodyContent.Add(output.Name, output);
            }
        }
    }


    private string GetSize(long size)
    {
        string result = "";
        if (size < 1000)
        {
            result = size.ToString() + " B";
        }
        if (size > 1000 && size < 1000000)
        {
            result = (size / 1000).ToString();
            //if split[1] contains a decimal then only include the first 2 numbers after the decimal
            if (result.Contains("."))
            {
                result = result.Substring(0, result.IndexOf(".") + 2);
            }
            result = result + " KB";
        }
        if (size > 1000000 && size < 1000000000)
        {
            result = (size / 1000000).ToString();
            //if split[1] contains a decimal then only include the first 2 numbers after the decimal
            if (result.Contains("."))
            {
                result = result.Substring(0, result.IndexOf(".") + 2);
            }
            result = result + " MB";
        }
        if (size > 1000000000)
        {
            size = size / 1000000000;
            result = size.ToString();
            //if split[1] contains a decimal then only include the first 2 numbers after the decimal
            if (result.Contains("."))
            {
                result = result.Substring(0, result.IndexOf(".") + 2);
            }
            result = result + " GB";
        }
        return result;
    }

    private bool FilterFunc1(FileSystemItem search) => FilterFunc(search, searchString1);

    private bool FilterFunc(FileSystemItem search, string searchString)
    {
        if (string.IsNullOrWhiteSpace(searchString))
        {
            return true;
        }
        //for each element in the array if it contains searchString then return true
        if (search.Name.Contains(searchString))
        {
            return true;
        }
        else if (search.Owner.Contains(searchString))
        {
            return true;
        }
        else
        {
            return false;
        }
        
    }

    private void PageChanged(int i)
    {
        _table.NavigateTo(i - 1);
    }

   
    protected override void OnParametersSet()
    {
        FillContents();
    }
    
}
